package com.xl.web.controller;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.xl.base.annotation.Auth;
import com.xl.base.entity.Operator;
import com.xl.core.util.PasswordUtil;
import com.xl.core.util.SessionLocalUtils;
import com.xl.core.util.SessionManager;
import com.xl.core.util.StringUtil;
import com.xl.base.web.BaseController;
import com.xl.core.enums.CommonEnum;
import com.xl.web.entity.sys.SysMember;
import com.xl.web.entity.sys.SysMenu;
import com.xl.web.entity.sys.SysMenuBtn;
import com.xl.web.service.sys.SysMemberService;
import com.xl.web.service.sys.SysMenuService;

/**
 * 登录控制器
 * 
 * @author 梁华
 * 
 */
@Controller
@Scope("prototype")
public class LoginController extends BaseController {

	// 注入用户数据service
	@Autowired(required = false)
	private SysMemberService<SysMember> memberService;

	// 注入菜单数据service
	@Autowired(required = false)
	private SysMenuService<SysMenu> sysMenuService;

	/**
	 * 跳转登录页面
	 * 
	 * @param entity
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/login")
	public ModelAndView login() throws Exception {

		Map<String, Object> context = getRootMap(request);

		// 获取redis存储的用户数据
		Operator operator = (Operator) SessionManager.get(request,
				CommonEnum.cookie_type.TYPE_01.getValue());
		// 如果用户已经登录，则跳转到main页面
		if (operator != null) {
			// 存入本服务器缓存中，用于提高访问速度
			SessionLocalUtils.setOperator(operator);
			// 重新设置session失效时间
			SessionManager.resetExpire(request,
					CommonEnum.cookie_type.TYPE_01.getValue());

			response.sendRedirect("main");
			return null;
		}

		return forword("bsa_login", context);
	}

	/**
	 * 登录验证
	 * 
	 * @param user
	 * @param req
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping("/loginCheck")
	public void loginCheck(SysMember member) throws Exception {

		// 验证码对比
		String randCode = request.getParameter("randCode");
		Object vCodeCheck = SessionManager.get(request,
				CommonEnum.cookie_type.TYPE_02.getValue());
		/*if (StringUtil.isEmpty(randCode)
				|| !randCode.toLowerCase().equals(String.valueOf(vCodeCheck).toLowerCase())) {
			sendFailureMessage(response, "验证码输入有误");
			return;
		}*/

		// 用户名与密码必输
		if (StringUtil.isEmpty(member.getMemName())
				|| StringUtil.isEmpty(member.getMemPwd())) {
			sendFailureMessage(response, "用户名或者密码错误");
			return;
		}

		// 判断登录用户是否合法
		SysMember checkMember = memberService.queryByName(member);

		// 用户不存在
		if (checkMember == null) {
			sendFailureMessage(response, "用户名或者密码错误");
			return;
		}

		// 密码验证
		String password = PasswordUtil.encrypt(member.getMemName(),
				member.getMemPwd(), PasswordUtil.getStaticSalt());
		password = member.getMemPwd();
		if (!password.equals(checkMember.getMemPwd())) {
			sendFailureMessage(response, "用户名或者密码错误");
			return;
		}

		// 判断账号是否已经停用
		if (CommonEnum.mem_status.STATUS_2.getValue() == checkMember
				.getMemStatus()) {
			sendFailureMessage(response, "账号未启用，请联系平台");
			return;
		}

		// 使用redis保存登录的信息，已适应可能会需要用到的分布式部署
		saveLoginSuccessInfo(request, response, checkMember);
		sendSuccessMessage(response, "登录成功");

		return;
	}

	/**
	 * 退出登录
	 * 
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@Auth(verifyLogin = true)
	@RequestMapping("/logout")
	public ModelAndView logout() throws Exception {

		Map<String, Object> context = getRootMap(request);

		// 清除redis存储的用户数据
		String sessionId = SessionManager.getSessionId(request,
				CommonEnum.cookie_type.TYPE_01.getValue());
		SessionManager.del(sessionId);

		// 清除cookie
		Cookie cookie = new Cookie(SessionManager.COOKIE_KEY
				+ CommonEnum.cookie_type.TYPE_01.getValue(), "");
		response.addCookie(cookie);

		// 过期回话
		HttpSession session = request.getSession();
		if (session != null) {
			session.invalidate();
		}

		return forword("bsa_login", context);
	}

	/**
	 * 使用redis保存登录的信息，已适应可能会需要用到的分布式部署
	 * 
	 * @param req
	 *            request
	 * @param member
	 *            当前登录用户
	 * @throws Exception
	 */
	private void saveLoginSuccessInfo(HttpServletRequest req,
			HttpServletResponse response, SysMember member) throws Exception {

		// 保存登录信息实体类
		Operator operator = new Operator();
		// 清空密码，防止泄露
		member.setMemPwd(null);

		// 整理后的菜单列表与权限列表
		List<SysMenu> checkedList = new LinkedList<SysMenu>();
		List<String> permissionsList = new ArrayList<String>();

		// 拥有的菜单
		Set<String> menuIdSet = new HashSet<String>();
		List<SysMenu> menuList = new ArrayList<SysMenu>();
		// 拥有的菜单按钮
		List<SysMenuBtn> menuBtnList = member.getMenuBtnList();

		if (menuBtnList != null && menuBtnList.size() > 0) {

			for (SysMenuBtn menuBtn : menuBtnList) {
				permissionsList.add(menuBtn.getBtnPermissions());
				if (!menuIdSet.contains(menuBtn.getMenuId())) {
					menuIdSet.add(menuBtn.getMenuId());
					menuList.add(sysMenuService.queryById(menuBtn.getMenuId()));
				}
			}

			// 整理用户拥有的菜单
			Map<String, List<SysMenu>> menuMap = new LinkedHashMap<String, List<SysMenu>>();
			// 菜单排序
			Collections.sort(menuList, new Comparator<SysMenu>() {
				@Override
				public int compare(SysMenu o1, SysMenu o2) {
					return o1.getCreateDate().compareTo(o2.getCreateDate());
				}
			});

			for (SysMenu menu : menuList) {
				if (menu.getParentMenu() != null
						&& !StringUtil.isEmpty(menu.getParentMenu().getId())) {

					if (!menuMap.containsKey(menu.getParentMenu().getId())) {
						List<SysMenu> childList = new ArrayList<SysMenu>();
						menuMap.put(menu.getParentMenu().getId(), childList);
					}

					menuMap.get(menu.getParentMenu().getId()).add(menu);
				}
			}

			// 遍历
			Iterator<String> it = menuMap.keySet().iterator();
			SysMenu checkedMenu = null;
			while (it.hasNext()) {
				String parentId = it.next();
				checkedMenu = sysMenuService.queryById(parentId);
				checkedMenu.setChildMenuList(menuMap.get(parentId));
				checkedList.add(checkedMenu);
			}
		}

		member.setMenuList(checkedList);
		member.setPermissionsList(permissionsList);
		
		operator.setMember(member);

		// 保存登录信息
		SessionManager.set(req, response, operator,
				CommonEnum.cookie_type.TYPE_01.getValue());
		// 存入本服务器缓存中，用于提高访问速度
		SessionLocalUtils.setOperator(operator);
	}
}
